package com.itheima.service;

import cn.hutool.json.JSONUtil;
import com.itheima.entity.User;
import com.itheima.entity.UserDto;
import com.itheima.mapper.UserMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.CachePut;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.List;

/**
 * @author sjqn
 */

@Slf4j
@Service
public class UserService {

    @Autowired
    private UserMapper userMapper;
    @Autowired
    StringRedisTemplate stringRedisTemplate;

    // #user.id : #user指的是方法形参的名称, id指的是user的id属性 , 也就是使用user的id属性作为key
    @CachePut(cacheNames = "userCache",key = "#user.id")
    public User insert(User user){
        userMapper.insert(user);
        return user;
    }





    //从缓存中读取信息都是以下这种写法
 /*   public User getById(Long id){
        String key = "user:"+id;
        //先读缓存
        String json = stringRedisTemplate.opsForValue().get(key);
        //如果缓存有 直接返回
        if(StringUtils.hasLength(json)){
            log.info("从【缓存】中获取到用户信息:id:{}",id);
            return JSONUtil.toBean(json,User.class);
        }
        //如果缓存没有的话 再查库
        log.info("从【数据库】中获取到用户信息:id:{}",id);
        User user = userMapper.getById(id);
        if(user == null){
            throw new RuntimeException("用户不存在");
        }
        //如果库中有 放入缓存就好了
        stringRedisTemplate.opsForValue().set(key,JSONUtil.toJsonStr(user));
        return user;
    }*/


    /**
     * 使用了这个注解之后当第一次请求来的时候会先检查缓存中有没有一个key叫 cacheNames+key的键
     * 如果没有的话就调用下面的方法，然后把返回结果存在缓存当中 key为注解的两个参数相加
     * 如果缓存中有的话就直接拿出来返回就好了
     * @param id
     * @return
     */
    @Cacheable(cacheNames = "userCache",key ="#id")
    //以下的注解的使用效果和上面的相同
    public User getById(Long id){
        User user = userMapper.getById(id);
        if(user == null){
            throw new RuntimeException("用户不存在");
        }
        return user;
    }




    //删除某个key对应的缓存数据 #id代表引用函数的形参
    @CacheEvict(cacheNames = "userCache",key = "#id")
    public void deleteById(Long id){
        userMapper.deleteById(id);
    }

    //删除userCache下所有的缓存数据 也就是删除所有以userCache打头的数据
    @CacheEvict(cacheNames = "userCache",allEntries = true)
    public void deleteAll(){
        userMapper.deleteAll();
    }

    //附件条件 ：如果返回结果为空，则不缓存unless="#result == null"或unless="#result.size()==0"
    //#result代表返回结果
    @Cacheable(cacheNames = "userCache",key = "#userDto.hashCode()",unless = "#result.size() == 0")
    public List<User> getList(UserDto userDto){
        List<User> list = userMapper.getList("%" + userDto.getName() + "%", userDto.getAge());
        return list;
    }

}
